#include <iostream>
struct Box {
    int* p;                       // 用指针就能体现“资源转移”
    Box(int n) : p(new int(n)) {}
    // 移动构造函数
    // 1、中noexcept关键字表示这个函数不会抛出异常
    // 2、移动构造函数的参数是一个右值引用（T&&），表示它可以绑定到一个将要被销毁的临时对象上
    // 3、在移动构造函数内部，我们将源对象的资源（这里是指针 p）“抢”过来，然后将源对象的指针置为空，防止源对象析构时释放资源
    // 4、移动构造函数通常会比拷贝构造函数更高效，因为它避免了不必要的资源复制
    Box(Box&& b) noexcept : p(b.p) {  // 抢指针
        b.p = nullptr;                // 把源对象置空，如果a销毁了，触发析构函数不会报错，是因为 b.p = nullptr
        std::cout << "移动\n";
    }
    ~Box() { delete p; }
};

int main() {
    Box a(42);
    Box b(std::move(a));   // 触发移动
    std::cout << "b.p=" << (b.p ? *b.p : -1) << '\n';
    std::cout << "a.p=" << (a.p ? *a.p : -1) << '\n';  // 空指针，打印 -1
    return 0;
}